package com.letv.so.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.rubyeye.xmemcached.MemcachedClient;

import org.apache.commons.lang.StringUtils;
import org.apache.thrift.TException;
import org.slf4j.Logger;

import rec.recommend.RecommendationRequest;
import rec.serving.sarrs.SarrsDetailRequest;
import rec.serving.sarrs.SarrsFavorTagsRequest;
import rec.serving.sarrs.SarrsKVItem;
import serving.AlbumAttribute;
import serving.DataType;
import serving.GenericDetailRequest;
import serving.GenericDetailResponse;
import serving.GenericWebSiteInfo;
import serving.GenericWebSiteRequest;
import serving.ResultDocInfo;
import serving.SourceLogo;
import serving.VideoAttributeInAlbum;
import serving.Website;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.letv.so.bean.AlbumBean;
import com.letv.so.bean.VideoBean;
import com.letv.so.constants.Constants;
import com.letv.so.service.QueryDataService;
import com.letv.so.service.VideoDetailService;
import com.letv.so.service.thrift.detail.CommonDetail;
import com.letv.so.util.BisUtil;
import com.letv.so.util.StringUtil;
import com.letv.so.util.ThreadLocalUtil;
import com.letv.user_profile.UserHistory;

public class VideoDetailServiceImpl implements VideoDetailService {

    private static Logger logger = org.slf4j.LoggerFactory.getLogger(VideoDetailServiceImpl.class);

    private QueryDataService dataService;
    private MemcachedClient memcachedClient;

    @Override
    public GenericDetailResponse GetDetailInfo(GenericDetailRequest request)
            throws TException {
        long beginTime = System.currentTimeMillis();
        GenericDetailResponse response = new GenericDetailResponse();
        List<String> ids = request.getIds();
        if (ids == null || ids.size() ==0 ) {
            response.setStatus(404);
            response.setMessage("bad request");
            return response;
        } else {
            int size = ids.size();
            Long sid = System.currentTimeMillis();
            String from = request.getFrom();
            logger.error("get from {},ids={}", from, ids);
            Map<String, String> paras = new HashMap<String, String>();
            ThreadLocalUtil.setParasMap(paras);
            ThreadLocalUtil.calculatePlatform(from);
            List<ResultDocInfo> result = new ArrayList<ResultDocInfo>();
            Short startidx = request.getVideo_list_start_idx();
            Short listNum = request.getVideo_list_num();
            Short cp_request_type = request.getCp_request_type();
            int fromIndex0 = startidx==null?0:startidx.intValue();
            int ps = listNum==null?0:listNum.intValue();
            int cpRequestType = cp_request_type==null ? 0 : cp_request_type.intValue();
            for (int i=0;i<size;i++) {
                String id = ids.get(i);
                if (result.size() >=30) {
                    break;
                }
                if (StringUtils.isNotEmpty(id) && (id.indexOf(Constants.LESO_ALBUM_PERFIX) == 0)) {
                    String lesoAid = dataService.getLesoAid(id);
                    if (StringUtils.isNotBlank(lesoAid)) {
                        Long t1 = System.currentTimeMillis();
                        String soKey = "newmms_leso_a_"+lesoAid;
                        String soData = dataService.get(sid.toString(),"inc"+soKey);// 获得cbase数据
                        if (StringUtils.isBlank(soData)) {
                             soData = dataService.get(sid.toString(),soKey);// 获得cbase数据
                        }
                        if (StringUtil.isBlank(soData)) {
                             logger.warn("soKey:"+soKey+" get val from cbase为空!");
                             continue;
                        }
                        AlbumBean album =null;
                        try {
                            album = JSON.parseObject(soData, AlbumBean.class);
                        } catch (Exception e) {
                            logger.error(sid+" ,parse album error", e);
                        }
                        if (album == null) {
                            logger.warn(sid+ " ,soKey:"+soKey+" album==null ");
                            continue;
                        }
                        try {
                            JSONObject source_list_json = album.getSource_list_json();
                            String source_list = null==source_list_json.getString("default") ? "" : source_list_json.getString("default");
                            if(!StringUtils.isBlank(source_list)) {
                                album.setSource_list(source_list);
                            }
                            album.setSource_list_json(null);
                        } catch(Exception e) {
                        }
                        if (ps > 0 && soKey.contains("newmms")) {// request要求有剧集列表，则封装
                            setVideoList(sid.toString(), soKey, album, fromIndex0,ps);
                        }
                        ResultDocInfo info = BisUtil.album2thrift(album);
                        info.setLetv_original_id(album.getLetv_original_id());
                        info.setData_type(DataType.ALBUM);
                        result.add(info);
                        logger.info("process aid={},use time:{}",id,System.currentTimeMillis()-t1);
                    } 
                }else if (StringUtils.isNotEmpty(id) && 
                        (id.indexOf(Constants.LESO_SHORTV_PERFIX) == 0 || id.indexOf(Constants.LETV_VIDEO_PERFIX) == 0
                                || id.indexOf(Constants.VRS_ALBUM_PERFIX) == 0)
                        || id.indexOf(Constants.LESO_VIDEO_PERFIX) == 0) {
                	String[] idarr = id.split("_");
                	if (idarr.length == 2) {
                        try {
                            byte[] docInfo = memcachedClient.get(id,new ByteTranscoder());
                            if ( docInfo!=null) {
                                logger.error("Docinfo length:{}",docInfo.length);
                                ResultDocInfo resultDoc = StringUtil.byte2ResultDocInfo(docInfo);
                                result.add(resultDoc);
                                if (resultDoc != null && resultDoc.getAlbum_attribute() != null) {
                                    Map<String, String> image = resultDoc.getAlbum_attribute().getImages();
                                    String defaultImg = "";
                                    if (image != null) {
                                        defaultImg = image.get("300*400");
                                    }
                                    image.put("default", defaultImg);
                                    resultDoc.getAlbum_attribute().setVideo_list(
                                            getSubVideoList(fromIndex0, fromIndex0 + ps, getVideoList(resultDoc, id)));
                                }
                            }
                        } catch (Exception e) {
                            logger.error("Docinfo:{}",e);
                        }
                	}
                }

                //===================== new code begin =====================
                // TODO now only cp detail use this method.
                // TODO all code in this for loop will use this method in future
                ResultDocInfo resultDocInfo = CommonDetail.getDetail(this.dataService, this.memcachedClient, id, sid, fromIndex0, ps, cpRequestType);
                if(null != resultDocInfo) {
                    result.add(resultDocInfo);
                }
                //===================== new code end =====================
            }
            if (result.size() > 0 ) {
                response.setStatus(200);
                response.setMessage("OK");
            } else {
                ResultDocInfo e = new ResultDocInfo("",DataType.ALBUM);
                result.add(e);
                response.setStatus(404);
                response.setMessage("not exsits element");
            }
            response.setDetails(result);
            long endTime = System.currentTimeMillis() - beginTime;
            logger.error("get from {},ids={},cost=" + endTime, from, ids);
            return response;
        }
    }

    private List<VideoAttributeInAlbum> getVideoList(ResultDocInfo resultDoc, String id) {
        List<VideoAttributeInAlbum> list = resultDoc.getAlbum_attribute().getVideo_list();
        if (id.indexOf(Constants.VRS_ALBUM_PERFIX) == 0
                && (String.valueOf(Constants.MMS_MOVIE).equals(resultDoc.getCategory())
                        || String.valueOf(Constants.MMS_TV).equals(resultDoc.getCategory()))) {
        	if ( list.size() > 0 ) {
        		int j=list.size()-1;
        		for (;j>0;j--) {
                    if (Constants.MMS_HUAXU.equals(list.get(j).getVideo_type()) ||
                            Constants.MMS_YUGAOPIAN.equals(list.get(j).getVideo_type())) {
        				continue;
        			} else {
        				break;
        			}
        		}
        		if (j<list.size()-1) {
        			list = list.subList(0, j+1);
        		}
        	}
        }
        return list;
	}

    /**
     * TODO this method will be deleted for some time.the new static method is at:
     * com.letv.so.service.thrift.detail.CommonDetail
     * In the meantime when you change this method, you must change the new static method for keeping synchronization
     * when all there is no caller calling this method,the method will be deleted,and all caller will use the new static method 
     * @param sid
     * @param soKey1
     * @param album
     * @param fromIndex
     * @param ps
     */
	private void setVideoList(String sid, String soKey1, AlbumBean album, int fromIndex, int ps) {
        String url = album.getUrl();
        String subSrc = album.getSubSrc();
        if (!StringUtil.isBlank(url) && (!StringUtil.isBlank(subSrc))
                && (Constants.WEBSITE_NETS.equals(subSrc) || "pan".endsWith(subSrc))) {
            int len = url.lastIndexOf('/') + 1;
            album.setPanid(url.substring(len));
            album.setSubSrc(Constants.WEBSITE_NETS);
        } else {
            album.setPanid("");
        }
        List<VideoBean> videoList = new ArrayList<VideoBean>();
        List<String>  tags = new ArrayList<String>();
        String videoPlayUrls = album.getVideoPlayUrls();
        //死链map
       if (!StringUtil.isBlank(videoPlayUrls)) {
            String avids = album.getOrderlist();
           List<String> orders = new ArrayList<String>();
           String[] videoArray = videoPlayUrls.split(";");
            String[] vidArray = avids.split(",");
            String[] durationsArray = album.getVideo_durations() == null ? new String[0]
                    : album.getVideo_durations().split(",");
            String[] typeArray = album.getVideo_types() == null ? new String[0] : album.getVideo_types().split(",");
           for (String vid : videoArray) {
               String[] videoFileds = vid.split("\\|");
               if (videoFileds.length==1) {//过滤不规范的数据
                   continue;
               }
               orders.add(videoFileds[0]);
           }
           List<String> vidLists = Arrays.asList(videoArray);
           int size = vidLists.size();
           int toIndex = fromIndex + ps;
           if (fromIndex >= size) {
               return;
           } else if ( fromIndex<size && toIndex > size ) {
                   toIndex = size;
           }
           List<String> retVids = new ArrayList<String>();
           List<String> retInfos = BisUtil.subList(fromIndex,toIndex,BisUtil.getList(album.getIntro()));
           List<String> subNames = BisUtil.subList(fromIndex,toIndex,BisUtil.getList(album.getVideoSubNames()));
           List<String> externalIds = BisUtil.subList(fromIndex, toIndex, BisUtil.getList(album.getExternalIds()));
           List<String> letvVids = BisUtil.subList(fromIndex, toIndex, BisUtil.getList(album.getVids()));
           List<String> letvOrininalSvidList = BisUtil.subList(fromIndex, toIndex, BisUtil.getList(album.getLetvOrininalSvids()));
           // 只有SARSS端需要外网流截图
           List<String> images = new ArrayList<String>();
            if (Constants.WEBSITE_LETV.equals(subSrc)) {
               images = BisUtil.subList(fromIndex,toIndex,BisUtil.getList(album.getVideoImages()));
           } else {
               images = BisUtil.subList(fromIndex,toIndex,BisUtil.getList(album.getVideoImages()));
           }
           List<String> deadinfo = new ArrayList<String>();
           List<String> payPlatforms = BisUtil.subList(fromIndex,toIndex,BisUtil.getList(album.getPayPlatform()));
           List<String> downloadPlatforms = BisUtil.subList(fromIndex,toIndex,BisUtil.getList(album.getDownloadPlatform()));
           List<String> ispays = BisUtil.subList(fromIndex,toIndex,BisUtil.getList(album.getIsPays()));
           List<String> mids = BisUtil.subList(fromIndex,toIndex,BisUtil.getList(album.getMids()));
           ArrayList<String> deadlinkList = new ArrayList<String>();
           String deadlinks = album.getDeadlinks();
           BisUtil.convertStr2List(deadlinks,deadlinkList);
           retVids = vidLists.subList(fromIndex, toIndex);
           deadinfo = deadlinkList.subList(fromIndex, toIndex);
           logger.info(sid+" ,"+soKey1+" SRC_LESO retVids fromIndex="+fromIndex+",toIndex="+toIndex+",videolist="+retVids.size());
           String aid = album.getAid();
           for (int i=0;i<retVids.size();i++) {
               String vid = retVids.get(i);
               if (StringUtil.isNotBlank(vid)) {
                   String[] videoFileds = vid.split("\\|");
                   if (videoFileds.length==1) {//过滤不规范的数据
                       continue;
                   }
                   String[] videoInfo = retInfos.size() > i ? retInfos.get(i).split("\\|") : new String[0];
                   String[] subName = subNames.size() > i ? subNames.get(i).split("\\|") : new String[0];
                   String[] image = images.size() > i ? images.get(i).split("\\|") : new String[0];
                   String[] ispayv = ispays.size() > i ? ispays.get(i).split("\\|") : new String[0];
                   String[] payPlatform = payPlatforms.size() > i ? payPlatforms.get(i).split("\\|") : new String[0];
                   String[] downPlatform = downloadPlatforms.size() > i ? downloadPlatforms.get(i).split("\\|") : new String[0];
                   String[] externelid = externalIds.size() > i ? externalIds.get(i).split("\\|") : new String[0];
                   String[] vids = letvVids.size() > i ? letvVids.get(i).split("\\|") : new String[0];
                   String[] letvOrininalSvidArray = letvOrininalSvidList.size() > i ? letvOrininalSvidList.get(i).split("\\|") : new String[0];
                   String[] mid = mids.size() > i ? mids.get(i).split(",") : new String[0];
                   VideoBean video = new VideoBean();
                   video.setDataType(Constants.VIDEO);
                   video.setAorder(videoFileds[0]);
                   video.setUrl(videoFileds[1]);
                    video.setSvid(vidArray.length > i ? vidArray[i] : null);
                    video.setDuration(durationsArray.length > i ? durationsArray[i] : null);
                    video.setVideoType(typeArray.length > i ? typeArray[i] : null);
                   video.setExternal_id(externelid.length > 1 ? externelid[1] : "");
                   video.setVid(vids.length > 1 ? vids[1] : null);
                   video.setName(videoInfo.length > 1 ? videoInfo[1] : "");
                   video.setSubName(subName.length > 1 ? subName[1] : video.getName());
                   video.setIsPay(ispayv.length > 1 ? ispayv[1] : "0");
                   video.setPayPlatform(payPlatform.length > 1 ? payPlatform[1] : null);
                   video.setDownloadPlatform(downPlatform.length > 1 ? downPlatform[1] : null);
                   video.setLetvOrininalSvid(letvOrininalSvidArray.length > 1 ? letvOrininalSvidArray[1] : null);
                   if (image.length > 1) {
                       try {
                           video.setImages(image[1]);
                       }catch(Exception e){
                           logger.error("parse images for single video,error album id="+album.getAid(),e);
                       }
                   } 
                   tags.add(videoFileds[0]);
                   String videoUrl = video.getUrl();
                    if (!StringUtil.isBlank(videoUrl) && (!StringUtil.isBlank(subSrc))
                            && (Constants.WEBSITE_NETS.equals(subSrc) || "pan".endsWith(subSrc))) {
                       int len = videoUrl.lastIndexOf('/') + 1;
                       video.setVideoPanid(videoUrl.substring(len));
                   } else {
                       video.setVideoPanid("");
                   }
                   //添加死链
                   if (deadinfo.size() > i) {
                       video.setDeadlink(deadinfo.get(i));
                   } else {
                       logger.debug(sid+" ,"+soKey1+",SRC_LESO videoPlayUrls 与 deadlinks 不匹配 ");
                       video.setDeadlink("0");
                   }
                   //每个视频添加唯一全局id
                   String porder = "1";
                   if (StringUtils.isNotBlank(video.getAorder())) {
                       porder = video.getAorder();
                   }
                   video.setMid(mid.length > 1 ? mid[1] : "");
                   video.setGlobal_vid(aid+"_"+porder+"_"+BisUtil.MD5(video.getUrl()));
                   BisUtil.setPayAndDownFlag(video);
                   videoList.add(video);
               } else {
                   tags.add("null");
               }
           }
           album.setSomePropertyNull();
           long st3 = System.currentTimeMillis();
           logger.debug(sid+" ,"+soKey1+",SRC_LESO tagList, cost time8=" + (System.currentTimeMillis()-st3));
           if (videoList.size() > 0) {
        	   logger.warn("videolist size={}",videoList.size());
               album.setVideoList(videoList);
           }
       }
    }

    @Override
    public List<SarrsKVItem> GetSarrsDetailsLimit(SarrsDetailRequest req)
            throws TException {
        return null;
    }

    @Override
    public void PutSarrs(SarrsKVItem unit) throws TException {
    }

    @Override
    public void PutSarrses(List<SarrsKVItem> units) throws TException {
    }

    @Override
    public int PutUserFavorTagsToCabase(SarrsFavorTagsRequest favor_tags_req)
            throws TException {
        return 0;
    }

    @Override
    public boolean PutUserWatchHistory(RecommendationRequest rec_req,
            UserHistory history) throws TException {
        return false;
    }

    public void setDataService(QueryDataService dataService) {
        this.dataService = dataService;
    }

    public MemcachedClient getMemcachedClient() {
        return memcachedClient;
    }

    public void setMemcachedClient(MemcachedClient memcachedClient) {
        this.memcachedClient = memcachedClient;
    }

	@Override
	public List<GenericWebSiteInfo> GetWebSiteInfo(GenericWebSiteRequest request) throws TException {
		return null;
	}

	@Override
	public GenericWebSiteInfo GetWebSiteVideoListInfo(GenericWebSiteRequest request) throws TException {
		GenericWebSiteInfo response = new GenericWebSiteInfo();
        String original_id = request.getLetv_original_id();
        Website website = request.getWebsite();
        logger.error("get website videolist,website={},gid={}", website, original_id);
        if (StringUtils.isNotBlank(original_id) && (original_id.indexOf(Constants.VRS_ALBUM_PERFIX) == 0
                || original_id.indexOf(Constants.LESO_ALBUM_PERFIX) == 0)) {
            String from  = "";
            try{
            	from = request.getFrom();;
            }catch (Exception e) {
                logger.error("get from error!,ids={}", original_id, e);
            }
            Map<String, String> paras = new HashMap<String, String>();
            ThreadLocalUtil.setParasMap(paras);
            ThreadLocalUtil.calculatePlatform(from);
            Short pn = request.getPagenum();
            Short listNum = request.getPagesize();
            int ps = listNum==null?50:listNum.intValue();
            String[] idarr = original_id.split("_");
            if (idarr.length == 2) {
                try {
                    byte[] docInfo = memcachedClient.get(original_id, new ByteTranscoder());
                    if ( docInfo!=null) {
                        logger.error("Docinfo length:{}",docInfo.length);
                        ResultDocInfo resultDoc = StringUtil.byte2ResultDocInfo(docInfo);
                        AlbumAttribute albumA = resultDoc.getAlbum_attribute();
                        response.setAid(albumA.getAid());
                        response.setEpisodes(albumA.getEpisodes());
                        response.setEpisodeStatus(albumA.getIs_end());
                        response.setLetv_original_id(Constants.VRS_ALBUM_PERFIX+albumA.getAid());
                        //response.setNowEpisodes(albumA);
                        response.setPlayStreams(albumA.getPlay_streams());
                        response.setTophot((short)1);
                        response.setVideo_list(
                                getSubVideoList(pn * ps, (pn + 1) * ps, getVideoList(resultDoc, original_id)));
                    }
                } catch (Exception e) {
                    logger.error("Docinfo:{}",e);
                }
        	}
        }
        return response;
	}

	private List<VideoAttributeInAlbum> getSubVideoList(int fromIndex, int toIndex, List<VideoAttributeInAlbum> video_list) {
		int size = video_list.size();
		List<VideoAttributeInAlbum> retVids =new ArrayList<VideoAttributeInAlbum>();
        if (fromIndex >= size || fromIndex >= toIndex) {
            return retVids;
        }
        if (toIndex > size) {
            toIndex = size;
		}
        retVids = video_list.subList(fromIndex, toIndex);
		return retVids;
	}
	
	@Override
	public List<SourceLogo> getAllSourceLogos() throws TException {
		List<SourceLogo> logoList = new ArrayList<SourceLogo>();
		String key =  "new_" + "logo";
		String logojson = dataService.get(key);
		if (logojson != null) {
			JSONArray jsonArr = JSON.parseArray(logojson);

			for (int i = 0; i < jsonArr.size(); i++) {
				JSONObject jsonObj = jsonArr.getJSONObject(i);
				SourceLogo logo = new SourceLogo();
				String sourceName = jsonObj.getString("sourceName");
				String logoUrl = jsonObj.getString("logoUrl");
				logo.setSource_name(sourceName);
				logo.setLogo_url(logoUrl);
				logoList.add(logo);
			}
		}
		return logoList;
	}

	@Override
	public SourceLogo getSourceLogoBySourceName(String sourceName) throws TException {
		SourceLogo logo = new SourceLogo();
		logo.setSource_name(sourceName);
		String key = "new_" + "logo_" + sourceName;
		String url = dataService.get(key);
		logo.setLogo_url(url);
		return logo;
	}

	@Override
	public int PutUserFavorToCbase(SarrsFavorTagsRequest arg0) throws TException {
		return 0;
	}
}
